<?php


namespace app\zyhsapi\model;


use app\zyhsapi\service\CacheZyhs;
use think\Cache;
use think\Log;
use XznsTools\cache\zyhs\CacheManageZyhs;

class ZyhsAstrTasks extends BaseCacheZyhs
{
    protected $table = 'good_wechat.zyhs_astr_tasks';

    protected $cacheModel = 'question_answer.astr_task';

    /**
     * 状态
     * 1=>待解答【已接单】
     * 2=>已弃答
     * 3=>已解答【可追问48小时后自动完成】
     * 4=>已解答【追问回复超时，不可追问48小时后自动完成】
     * 5=>追问待解答
     * 6=>已完成
     * 7=>答案回复超时
     * 8=>已完成且收益扣除【用户申述已取消】
     * 9=>已完成且收益扣除【追问回复超时未完成】
     */

    /**
     * 新增 接单记录
     * @param int $astrId
     * @param $data
     * @return int
     */
    public function SaveData(int $astrId, $data)
    {
        try
        {
            $id = $this->insertGetId($data);
            // 记录已经 任务ID
            $this->listDataAdd($astrId, [$data['qid'] => $data['create_time']], 10);    // 缓存以咨询ID为key type=1 进行中 0=>全部结束任务 2=>已弃答 3=>已完成 10=>已接任务ID
            // 添加至 进行中任务
            $this->listDataAdd($astrId, [$id => $data['create_time']], 1);    // 缓存以咨询ID为key type=1 进行中 0=>全部结束任务 2=>已弃答 3=>已完成
            Cache::set('question_answer:is_underway:' . $astrId, 1, 86400); // 记录占星师当前有进行中的任务

            return (int)$id;
        }
        catch (\Exception $e)
        {
            Log::write('问答 Zlcr2AstrTasks model => SaveData()异常：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error');
            return 0;
        }
    }

    /**
     * 更新 接单记录
     * @param int $id
     * @param int $astrId
     * @param array $data
     * @return bool
     */
    public function UpdateData(int $id, int $astrId, array $data)
    {
        try
        {
            $this->where(['id' => $id])->update($data);

            if (isset($data['status']))
            {
                if ($data['status'] === 6)
                {
                    $this->listDataAdd($astrId, [$id => $data['update_time']], 3);    // 缓存以咨询ID为key type=1 进行中 0=>全部结束任务 2=>已弃答 3=>已完成
                }
                // 状态
                //  1=>待解答【已接单】
                //  2=>已弃答
                //  3=>已解答【可追问48小时后自动完成】
                //  4=>已解答【追问回复超时，不可追问48小时后自动完成】
                //  5=>追问待解答
                //  6=>已完成
                //  7=>答案回复超时
                //  8=>已完成且收益扣除【用户申述已取消】
                //  9=>已完成且收益扣除【追问回复超时未完成】
                if (in_array($data['status'], [2, 7], true))
                {
                    $this->listDataAdd($astrId, [$id => $data['update_time']], 2);    // 缓存以咨询ID为key type=2 已弃答
                }
                // 进行中删除
                if (!in_array($data['status'], [1, 3, 5], true))
                {
                    $this->listDataDel($astrId, [$id], 1);
                }

                if ($data['status'] !== 1)
                {   // 进行中 的任务 与准了 通用
                    Cache::rm('question_answer:is_underway:' . $astrId); // 移除进行中的任务
                }
            }

            CacheManageZyhs::getInstance()->setCacheConfig($this->cacheModel, $id)->setCache($data);

            return true;
        }
        catch (\Exception $e)
        {
            Log::write('问答 ZyhsAstrTasks model => UpdateData()异常：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error');
            return false;
        }
    }

    /**
     * 重写数据时获取数据
     * @param $ids
     * @param $type
     * @param $sortType
     * @return array|false|string
     */
    public function getInfoByIdsInData($ids, $type, $sortType)
    {
        try
        {
            if ($ids)
            {
                $model = $this->where('id', 'in', $ids);
            } else
            {

                // 当前支持 $type[1]=1 或 $type[1]=3 其他类型搜索不支持
                $model = $this->where(['astr_id' => $type[0]]);
                // 状态
                //  1=>待解答【已接单】
                //  2=>已弃答
                //  3=>已解答【可追问48小时后自动完成】
                //  4=>已解答【追问回复超时，不可追问48小时后自动完成】
                //  5=>追问待解答
                //  6=>已完成
                //  7=>答案回复超时
                //  8=>已完成且收益扣除【用户申述已取消】
                //  9=>已完成且收益扣除【追问回复超时未完成】
                if ($type[1] == 1)
                {   // 进行中
                    $model = $model->where(['status' => ['in', [1, 3, 5]]]);
                }
                if ($type[1] == 3)
                {   // 已完成
                    $model = $model->where(['status' => 6])->limit(20);
                }
            }

            $data = $model
                ->order('id', 'DESC')
                ->column('id,uid,qid,astr_id,level,question_type,status,create_time,update_time,earning,lock_earning,deduct_earning_time,is_lock_receiving,look_num,answer_duration,answer_content,reply_time,is_comment,complain_status,aid,atime,lock_reason,success_time', 'id');
        }
        catch (\Exception $e)
        {
            $data = [];
        }

        return $data;
    }

    public function batchGetInfoByIds($cids, $field = [])
    {
        $resData = parent::batchGetInfoByIds($cids, $field);

        return $this->dataInit($resData);
    }

    /**
     * 数据初始化
     * @param array $data
     * @return array
     */
    public function dataInit(array $data)
    {
        foreach ($data as $index => $itemData)
        {
            $data[$index] = arrayKeyData2int($itemData, ['id', 'uid', 'astr_id', 'level', 'question_type', 'status', 'create_time', 'update_time', 'lock_earning', 'deduct_earning_time', 'is_lock_receiving', 'look_num', 'answer_duration', 'reply_time', 'is_comment', 'complain_status', 'aid', 'atime', 'success_time']);
        }

        return $data;
    }

    /**
     * 获取72小时内弃答的qids
     * @param int $astrId
     * @return array
     * @throws \Exception
     */
    public function getDiscardQids(int $astrId)
    {
        $cacheModel = CacheManageZyhs::getInstance()->setCacheConfig($this->cacheModel, $astrId)->setListKeyType(2);// 类型 type=2 已弃答
        $redis = $cacheModel->redisHandler;
        $time = time();
        if ($redis->exists($cacheModel->cacheKey['list']))
        {   // 缓存存在
            $taskIds = $redis->zRangeByScore($cacheModel->cacheKey['list'], $time - 259200, $time);
        } else
        {   // 缓存丢失
            $questionData = $this->where(['status' => 2, 'astr_id' => $astrId, 'update_time' => ['>', $time - 259200]])->column('update_time', 'id');
            $pipe = $redis->multi($redis::PIPELINE);
            $pipe->zAdd($cacheModel->cacheKey['list'], [], 0, 0);
            $taskIds = [];
            foreach ($questionData as $taskId => $updateTime)
            {
                $pipe->zAdd($cacheModel->cacheKey['list'], [], $updateTime, $taskId);
                $taskIds[] = $taskId;
            }
            $pipe->exec();
            $redis->expire($cacheModel->cacheKey['list'], 86400);  // 1天过期时间
        }

        $qids = $this->batchGetInfoByIds($taskIds, ['qid']);

        return $qids ? array_column($qids, 'qid') : [];
    }

    /**
     * 获取占星师3日内弃答次数
     * @param int $astrId
     * @return int
     * @throws \Exception
     */
    public function getAstrDiscardQuestionNumByToday(int $astrId): int
    {
        $qids = $this->getDiscardQids($astrId);

        return count($qids);
    }

    /**
     * 获取 问答进行中 状态 描述
     * @param int $astrId
     * @return string
     * @throws \think\Exception
     */
    public function getUnderwayDes(int $astrId)
    {
        /**
         * 准有好事
         * 状态
         * 1=>待解答【已接单】
         * 2=>已弃答
         * 3=>已解答【可追问48小时后自动完成】
         * 4=>已解答【追问超时，不可追问48小时后自动完成】
         * 5=>追问待解答
         * 6=>已完成
         * 7=>答案回复超时
         * 8=>已完成且收益扣除【用户申述已取消】
         * 9=>已完成且收益扣除【追问回复超时未完成】
         */
        if ($this->where(['astr_id' => $astrId, 'status' => 5])->count())
        {
            return '有追问';
        }

        return '';
    }

    /**
     * 任务退款
     * @param int $taskId
     * @param string $reason
     * @return array
     * @throws \Exception
     */
    public function refund(int $taskId, string $reason)
    {
        $taskInfo = $this->getInfoById($taskId, ['qid', 'order_num']);
        $questionInfo = (new ZyhsUserQuestion())->getInfoById($taskInfo['qid'], ['consult_num', 'good_amount']);
        $refundCoin = 0;
        //每人的单价
        $refundTaskCoin = $questionInfo['good_amount'] / $questionInfo['consult_num'];
        (new ZyhsOrders())->refund($taskInfo['order_num'], $refundTaskCoin / 10, $reason);
        $refundCoin += $refundTaskCoin;
        request()->get(['page' => -1]);
        $addList = (new ZyhsUserAddQuestion())->getListPage($taskId, 'id', [], 0, 'asc');
        foreach ($addList['data'] as $datum)
        {
            if (in_array((int)$datum['status'], [2, 4], true))
            {
                (new ZyhsOrders())->refund($datum['order_num'], $datum['good_amount'] / 10, $reason);
                $refundCoin += $datum['good_amount'];
            }
        }
        return [
            'status' => true,
            'refund_amount' => $refundCoin,
        ];
    }

    /**
     * 获取占星师已收款的qids
     * @return array
     */
    public function getAstroReceivedQid(int $astrId)
    {
        $cacheModel = CacheManageZyhs::getInstance()->setCacheConfig($this->cacheModel, $astrId)->setListKeyType(10);// 类型 type=2 已弃答 10=>已接单过的问题ID
        $redis = $cacheModel->redisHandler;
        $time = time();
        if ($redis->exists($cacheModel->cacheKey['list']))
        {   // 缓存存在 取 12小时 以内的接单问题IDS
            $qids = $redis->zRangeByScore($cacheModel->cacheKey['list'], $time - 43200, $time);
        } else
        {   // 缓存丢失
            $questionData = $this->where(['astr_id' => $astrId, 'create_time' => ['>', $time - 43200]])->column('create_time', 'qid');
            $pipe = $redis->multi($redis::PIPELINE);
            $pipe->zAdd($cacheModel->cacheKey['list'], [], 0, 0);
            $qids = [];
            foreach ($questionData as $qid => $createTime)
            {
                $pipe->zAdd($cacheModel->cacheKey['list'], [], $createTime, $qid);
                $qids[] = $qid;
            }
            $pipe->exec();
            $redis->expire($cacheModel->cacheKey['list'], 86400);  // 1天过期时间
        }

        return $qids;
    }
}
